Sprite画像を使用してページ表示を高速化 レスポンシブ対応
TL;DR
Sprite画像を使用することで画像を多く使っているサイトは大幅な高速化を見込める。
可能だとしても クラスを変更する必要があった。(このheight 等を変えても正常に動作しない)
具体的には以下のようなclassを作っていた
.icon-name height: 64px; width 64px;
.icon-name-small height: 48px; width 48px;
レスポンシブに対応していなかったため、レスポンシブに対応したSprite画像+CSSを生成する
今回参考にしたものは下記のスプライトジェネレータの生成後のコード
多少の制約がつくが、非常に簡単にSpriteイメージをレスポンシブに対応させることができる
制約は以下のようなもの
すべてのイメージが同サイズ
生成される統合後のイメージが縦並び
CSS Sprite Generator
参考にしたSprite Generatorで生成される画像とコードは以下
https://gyazo.com/8c4ad2bfab8e2c05b28f46a5d52f37d4
code: sprite.css
.chainvest,
.cursedblade,
.darkin
{ max-width: 100%; background-size: 100%; background-image: url('png.png'); }
.chainvest { background-position: 0 0%; background-size: 100%; }
.cursedblade { background-position: 0 50%; background-size: 100%; }
.darkin { background-position: 0 100%; background-size: 100%; }
code:sprite.html
<img class="bfsword" alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAA9JREFUeNpjYBgFo4B8AAACQAAB4E0dRAAAAABJRU5ErkJggg==">
<img class="bladeoftheruinedking" alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAA9JREFUeNpjYBgFo4B8AAACQAAB4E0dRAAAAABJRU5ErkJggg==">
<img class="chainvest" alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAQMAAACQp+OdAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAA9JREFUeNpjYBgFo4B8AAACQAAB4E0dRAAAAABJRU5ErkJggg==">
<img> タブにheightとwidthを設定することでリサイズ可能
https://gyazo.com/e9ea6427089bfe3e0f6b98e24c847066
個別に指定するCSS
.chainvest { background-position: 0 50%; background-size: 100%; }
それぞれのクラスで background-positionを設定して、画像の表示範囲を定めている
縦1列に並べているSpriteイメージのため、、 background-positionの第一引数(x軸)は常に0
第二引数(y軸)は、画像枚数をn、 順番をiとすると 100/(n-1)*(i-1) になる
画像が6枚なら上から順に 0% 20% 40% 60% 80% 100%となる
今回生成したコード
webpack-spritesmith を使って生成した。生成したコードは以下のようなコード
code: sprite.css
.icon-champion
height 64px
width 64px
display: inline-block
max-width 100%
background-image url("/img/sprite/champion-sprite.jpg")
background-size 100%
.icon-aatrox
background-position 0 0%
.icon-ahri
background-position 0 1.9607843137254901%
.icon-akali
background-position 0 3.9215686274509802%
.icon-anivia
background-position 0 5.88235294117647%
...
使用方法は<img class="icon-champion icon-aatrox" alt="aatrox"> のようにクラスで指定してsrcは書かない
全体にかかわる設定を icon-champion で設定し、個別の設定を icon-name で行う
特に設定しない場合は、初期値の64px 64pxで表示される。
サイズを変更したい場合はicon-champion のheight widthを上書きするか他のCSSで上書きすれば良い
webpack-spritesmith
CSSを生成するテンプレート
code:template.js
const spriteTemplate = setting => data => {
// setting: {suffix: string}
const iconTotalCount = data.sprites.length;
let stringBuilder = "";
stringBuilder += '.icon-A\n height Hpx\n width Wpx\n display: inline-block\n max-width 100%\n background-image url("/I")\n background-size 100%\n'
.replace("A", setting.suffix)
.replace("I", data.sprites0.image) .replace("H", data.sprites0.height) .replace("W", data.sprites0.width); stringBuilder += data.sprites
.map((sprite, index) => {
return ".icon-N\n background-position 0 Y%\n"
.replace("N", sprite.name.toLowerCase())
.replace("Y", (100 / (iconTotalCount - 1)) * index);
}).join("");
return stringBuilder;
};
Webpack内の設定
code: smith.js
new SpritesmithPlugin({
src: {
cwd: path.resolve(__dirname, "src/ico/item"),
glob: "*.jpg"
},
customTemplates: {
spriteFunctionItem: spriteTemplate({ suffix: "item" }) // icon-xxxのxxxに入るsuffixを設定
},
target: {
image: path.resolve(__dirname, "src/ico/sprite/item-sprite.jpg"),
css: [
[
path.resolve(__dirname, "src/style/sprite-item.styl"),
{ format: "spriteFunctionItem" }
]
]
},
apiOptions: {
cssImageRef: "img/sprite/item-sprite.jpg"
},
spritesmithOptions: {
algorithm: "top-down" // 画像をすべて縦並びにする
}
})